-- UILogin
-- Create by zouyb
-- 登录界面

-- UILogin继承自Layer
UILogin = class("UILogin", function()
    return cc.Layer:create();
end);

function UILogin.create()
    return UILogin.new();
end

-- 英文版本开始按钮的偏移量
local START_BTN_OFFSET = 220;

-- 连接超时时间（秒）
local TIME_OUT_LIMIT = 120;

-- 是否启用新版的青瓷登录界面
local ENABLE_NEW_QC_FORM = false;

-- 构造函数
function UILogin:ctor()
    print("country code:" .. cc.Device:getCountryCode());

    self:setName("UILogin");

    -- 初始化
    local node = cc.CSLoader:createNode("layout/login/Login.csb");
    self:addChild(node);
    self.node = node;

    -- 获得初始光效
    self.initEffects = LoginEffectM.getLoginEffectList();

    -- 检查下节日背景
    local bgIconPath = self.initEffects["bg_path"];
    local bg = findChildByName(self.node, "bg");
    if bgIconPath ~= nil then
        bg:loadTexture(bgIconPath);
    end

    -- 覆盖在背景上面图
    local upperBgInfo = self.initEffects["upper_bg_info"];
    local upperBg = findChildByName(self.node, "bg/upper_bg");
    if type(upperBgInfo) == "table" then
        upperBg:loadTexture(upperBgInfo["path"]);
        upperBg:setPositionY(upperBg:getPositionY() + upperBgInfo["offset_y"]);
        upperBg:setPositionX(upperBg:getPositionX() + upperBgInfo["offset_x"]);
        upperBg:setVisible(true);
    end

    -- 先去拉取WEB公告
    GameBoardM.WebcheckGameBoard();

    -- 重新加载Config, 获取最新的SUPPORT_VERSION值
    package.loaded["Config"] = false;
    require "Config";
    print("SUPPORT_VERSION:" .. SUPPORT_VERSION);

    -- SLIMEC-2548 移到这边，弹出公告逻辑流程不需要这些
    if isAndroidPlatform() then
        if isQCPackage() and ENABLE_NEW_QC_FORM then
            require "game/ui/form/login/android/UIChannelSelectQC"
        else
        require "game/ui/form/login/android/UIChannelSelect"
        end
    elseif isIosPlatform() then
        require "game/ui/form/login/ios/UIChannelSelect"
    end

    require "game/base/encrypt/MyRc4"
    require "game/base/encrypt/MyBase64"

    -- 清空所有纹理
    UIMgr.cleanTextures();

    self:init();

    -- 注册事件回调处理函数
    self:registerEventCallback();

    self:registerBackKeyEventHandler();

    -- 处理系统信息按钮
    self:systemBtn();

    -- 适配
    self:resize();

    local function callback()
        self:tryAutoLogin();
    end

    -- 延迟执行自动登陆
    performWithDelay(self.node, callback, 3);

    -- 创建一个节点专门用于处理各种定时器事件
    local timerNode = cc.Node:create();
    self.node:addChild(timerNode);
    self.timerNode = timerNode;
end

-- 初始化
function UILogin:init()
    local node = self.node;

    local ct = node:getChildByName("ct");
    self.ct = ct;

    -- 显示客户端版本号
    local clientVersion = LoginM.getClientVersion();

    local version = node:getChildByName("version");
    version:setString("ver:"..clientVersion);
    version:setFontSize(TextStyleM.TEXT_SIZE_SMALL);

    -- 不同语言版本需要有偏移
    local offset = -40;

    if not isFullWidthLang() then
        offset = 0;
    end

    local userNameLabel = ct:getChildByName("user_label");
    userNameLabel:setPositionX(userNameLabel:getPositionX() + offset);
    TextStyleM.setTextStyle(userNameLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -2);
    userNameLabel:setString(getLocStr("user_name"));

    local passwordLabel = ct:getChildByName("passwd_label");
    passwordLabel:setPositionX(passwordLabel:getPositionX() + offset);
    TextStyleM.setTextStyle(passwordLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -2);
    passwordLabel:setString(getLocStr("login_passwd"));

    local nameInput = ct:getChildByName("input_name");
    local passwdInput = ct:getChildByName("input_passwd");
    local nameInputBg = ct:getChildByName("bg4");
    local passwdInputBg = ct:getChildByName("bg5");
    nameInput:setPositionX(nameInput:getPositionX() + offset);
    passwdInput:setPositionX(passwdInput:getPositionX() + offset);
    nameInputBg:setPositionX(nameInputBg:getPositionX() + offset);
    passwdInputBg:setPositionX(passwdInputBg:getPositionX() + offset);

    local visibleOrigin = cc.Director:getInstance():getVisibleOrigin();
    local visibleSize = cc.Director:getInstance():getVisibleSize();
    local editBoxSize = nameInput:getContentSize();

    -- 用户名
    local editName = ccui.EditBox:create(editBoxSize, "images/ui/login/1.png");
    editName:setAnchorPoint(cc.p(0, 0.5));
    editName:setPosition(nameInput:getPosition());
    editName:setFontName(getLocFontName());
    editName:setFontSize(TextStyleM.TEXT_SIZE_SMALL2);
    editName:setPlaceholderFontColor(TextStyleM.TEXT_COLOR_GRAY2);
    editName:setPlaceholderFontSize(TextStyleM.TEXT_SIZE_SMALL2);
    editName:setPlaceHolder(getLocStr("please_input_username"));
    editName:setFontColor(TextStyleM.TEXT_OUTLINE_COLOR_DARK);
    editName:setMaxLength(32);
    editName:setInputMode(cc.EDITBOX_INPUT_MODE_SINGLELINE);
    editName:setReturnType(cc.KEYBOARD_RETURNTYPE_DONE);
    self.editName = editName;
    nameInput:getParent():addChild(editName);
    nameInput:setVisible(false);

    local saveName = UserDefaultM.getStringForKey("UserName");
    if saveName ~= nil and saveName ~= "" then
        saveName = AccountM.removeTabAndSpace(saveName);
        editName:setText(saveName);
    end

    -- 密码
    local editPassword = ccui.EditBox:create(editBoxSize, "images/ui/login/1.png");
    editPassword:setAnchorPoint(cc.p(0, 0.5));
    editPassword:setPosition(passwdInput:getPosition());
    editPassword:setFontName(getLocFontName());
    editPassword:setFontSize(TextStyleM.TEXT_SIZE_SMALL2);
    editPassword:setPlaceHolder(getLocStr("please_input_passwd"));
    editPassword:setPlaceholderFontColor(TextStyleM.TEXT_COLOR_GRAY2);
    editPassword:setPlaceholderFontSize(TextStyleM.TEXT_SIZE_SMALL2);
    editPassword:setFontColor(TextStyleM.TEXT_OUTLINE_COLOR_DARK);
    editPassword:setMaxLength(32);
    editPassword:setInputFlag(cc.EDITBOX_INPUT_FLAG_PASSWORD);
    editPassword:setInputMode(cc.EDITBOX_INPUT_MODE_SINGLELINE);
    self.editPassword = editPassword;
    passwdInput:getParent():addChild(editPassword);
    passwdInput:setVisible(false);

    local lastPassword = self:getLastPassword();
    if type(lastPassword) == "string" and string.len(lastPassword) > 0 then
        editPassword:setText(lastPassword);
        end

    --"进入游戏"按钮点击处理
    local enterGameBtn = ct:getChildByName("enter_game");
    local function onBtnClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
             AudioM.playFx("button_click");
             self:tryLogin();
        end
    end
    enterGameBtn:addTouchEventListener(onBtnClick);
    TextStyleM.setTextStyle(enterGameBtn, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    enterGameBtn:setTitleText(getLocStr("login_game"));

    -- 返回按钮
    local backBtn = ct:getChildByName("back");
    TextStyleM.setTextStyle(backBtn, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    backBtn:setTitleText(getLocStr("btn_text_back"));
    backBtn:addTouchEventListener(function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");
            self:setLoginFormVisible(false);
        end
    end);

    local function startGame()
        AudioM.playFx("button_click");

        -- 如果系统正在维护中，弹出提示
        if MaintainBulletinM.isSysMaintaining() and not isInWhiteList() then
            -- 获取公告配置
            local bulletin = MaintainBulletinM.getMaintainBulletin();
            if type(bulletin) == "table" then
                self:showMaintainConfirm(bulletin);
                return;
            end
        end

        -- 如果是安卓或ios平台
        if isAndroidPlatform() or isIphonePlatform() or isIpadPlatform() then
            if self:isShowChannelSelect() then
                local lastChannel = getLastAccountChannel();
                if lastChannel == "" then
                    -- 从未登录过，打开渠道选择窗口
                    self:showChannelSelect();
                else
                    if isGuestChannel(lastChannel) then
                        if type(self.bindedAccounts) == "table" then
                            self:limitGuestFunc();
                        else
                            -- 最近一次使用的是游客登录，尝试游客登录
                            if LoginM.tryGuestLogin() then
                                self:enterCommunicateMode();
                            end
                        end
                    elseif not EXPRESS_LOGIN and hasLogin3rdPlatform(lastChannel) then
                        -- 已经登录了第三方平台账号，直接请求服务器认证
                        auth3rdPlatform(lastChannel);
                        self:enterCommunicateMode();
                    else
                        -- 默认走上次的渠道
                        -- 打上登录请求标识
                        local path = string.format("request_%s_login", lastChannel);
                        _G[path] = true;

                        show3rdAccountLogin(lastChannel);
                    end
                end
            elseif type(PUBLISH_PLATFORM) == "string" and
                   PUBLISH_PLATFORM ~= "" and
                   PUBLISH_PLATFORM ~= PUBLISH_TYPE_QC then
                -- 除青瓷平台外的第三方账号登录
                local lastChannel = getLastAccountChannel();
                if lastChannel ~= "" and hasLogin3rdPlatform(lastChannel) then
                    -- 已经登录了第三方账号，直接请求服务器认证
                    auth3rdPlatform(lastChannel);
                    self:enterCommunicateMode();
                else
                    -- 目前国内的运营平台都只有一个第三方账号渠道，所以这里暂时先使用 PUBLISH_PLATFORM 作为channel
                    lastChannel = PUBLISH_PLATFORM;

                    -- 打上登录请求标识
                    local path = string.format("request_%s_login", lastChannel);
                    _G[path] = true;

                    -- 打开第三方账号登录窗口
                    self:show3rdAccountLogin(lastChannel);
                end
            else
                -- 显示普通登录窗口
                self:setLoginFormVisible(true);
            end
        else
            -- 显示登录窗口
            self:setLoginFormVisible(true);
        end
    end

    -- 点击开始游戏
    local startImg = findChildByName(self.node, "ct2/start/bg");
    local startLabel = findChildByName(self.node, "ct2/start/start_label");
    TextStyleM.setTextStyle(startLabel, TextStyleM.TEXT_SIZE_LARGE, TextStyleM.TEXT_COLOR_BLACK, false, 10);
    local startPanel = findChildByName(self.node, "ct2/start/reciever");
    startLabel:setString(getLocStr("login_start_text"));

    self:resizeStartBg(startLabel, startImg);
    if getLang() ~= "zh" and getLang() ~= "tw" then
        startImg:setPositionY(startImg:getPositionY() + START_BTN_OFFSET);
        startLabel:setPositionY(startLabel:getPositionY() + START_BTN_OFFSET);
        startPanel:setPositionY(startPanel:getPositionY() + START_BTN_OFFSET - 20);
        startPanel:setContentSize(600, 350);
    else
        startImg:setPositionY(startImg:getPositionY() + START_BTN_OFFSET);
        startLabel:setPositionY(startLabel:getPositionY() + START_BTN_OFFSET);
        startPanel:setPositionY(startPanel:getPositionY() + START_BTN_OFFSET - 20);
    end

    startPanel:addTouchEventListener(function(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 限制点击频率
            setClickFrequency(sender, 1.0);

            startGame();
        end
    end);

    local bgNode = findChildByName(self.node, "bg");

    local function onBgClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then

        elseif eventType == ccui.TouchEventType.ended then
            bgNode:stopAllActions();

            -- 点击背景，略过动画
            local startNode = findChildByName(self.node, "ct2/start");
            if self.canSkipAnimation and self.loginEffect2 and self.loginEffect2.action then
                self.loginEffect1.action:gotoFrameAndPlay(104, false);
                self.loginEffect2.action:gotoFrameAndPlay(104, false);
                self.canSkipAnimation = false;
                if not self.ct:isVisible() then
                    startNode:setVisible(true);
                end
            end
        end
    end
    bgNode:addTouchEventListener(onBgClick);

    -- 初始登陆框不可见
    self:setLoginFormInvisible();

    local accountSwitchBtn = findChildByName(self.node, "account_switch");
    local accountRegBtn = findChildByName(self.node, "account_reg");

    if PUBLISH_PLATFORM == PUBLISH_TYPE_AMAZON then
        accountSwitchBtn:loadTextures("images/ui/login/account_switch_am_1.png", "images/ui/login/account_switch_am_2.png");
    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE or PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE_CN then
        accountSwitchBtn:loadTextures("images/ui/login/account_gamecenter_1.png", "images/ui/login/account_gamecenter_2.png");
    else
        accountSwitchBtn:loadTextures("images/ui/login/account_switch_1.png", "images/ui/login/account_switch_2.png");
    end

    -- 如果需要显示渠道选择窗口
    if self:isShowChannelSelect() then
        accountSwitchBtn:setVisible(false);
        local function onAccountSwitchClick(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                if not UIChannelSelect then
                    cclog("没有UIChannelSelect可用");
                    return;
                end

                -- 打开渠道选择窗口
                UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
                local UIChannelSelect = UIChannelSelect.create();
                UIMgr.getCurrentScene():addForm(UIChannelSelect);
            end
        end
        accountSwitchBtn:addTouchEventListener(onAccountSwitchClick);
        accountRegBtn:setVisible(false);

    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_QC then
        -- 青瓷平台
        accountSwitchBtn:setVisible(false);

        -- 显示青瓷账号注册
        accountRegBtn:setVisible(true);
        local function onAccountRegClick(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                print("openUrl")
                openUrl("http://account.qcplay.com/Reg");
            end
        end
        accountRegBtn:addTouchEventListener(onAccountRegClick);
    else
        accountSwitchBtn:setVisible(false);
        accountRegBtn:setVisible(false);
    end
end

-- 获取最近一次使用的密码
function UILogin:getLastPassword()
    local password = UserDefaultM.getStringForKey("Password");
    local final = "";
    if password ~= nil and password ~= "" then
        local data = "";
        local function tryDecode()
            data = MyBase64.decode(password);
        end
        if pcall(tryDecode) then
            final = MyRc4.encrypt(data, "kkkk");
        end

        print("raw:"..password..",decode:"..final);
    end
    return final;
end

-- 是否显示渠道选择窗口
function UILogin:isShowChannelSelect()
    -- 需要显示渠道选择窗口的运营平台
    local platforms = {
        PUBLISH_TYPE_GOOGLE_PLAY,
        PUBLISH_TYPE_APP_STORE,
        PUBLISH_TYPE_AMAZON,
        PUBLISH_TYPE_APP_STORE_CN,
    };

    if table.indexOf(platforms, PUBLISH_PLATFORM) ~= -1 then
        return true;
    end

    -- 如果是青瓷平台，并且开启了新版登录界面
    if isQCPackage() and ENABLE_NEW_QC_FORM then
        return true;
    end

    return false;
end

-- 显示渠道选择窗口
function UILogin:showChannelSelect()
    if isQCPackage() then
        UIMgr.getCurrentScene():removeFormByName("UIChannelSelectQC");
        local uiChannelSelectQC = UIChannelSelectQC.create();
        UIMgr.getCurrentScene():addForm(uiChannelSelectQC);
    else
        UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
        local uiChannelSelect = UIChannelSelect.create();
        UIMgr.getCurrentScene():addForm(uiChannelSelect);
    end
end

-- 进入通信显示模式
function UILogin:enterCommunicateMode()
    -- 显示通信中
    showCommunicatingForm(nil, true, false, nil, "login");

    -- 连接超时处理
    local function timeOutFunc()
        showHint2(getLocStr("hint"), getLocStr("disconnect"));
        closeCommunicatingForm();
    end
    performWithDelay(self.timerNode, timeOutFunc, TIME_OUT_LIMIT);
end

-- 注册事件回调处理函数
function UILogin:registerEventCallback()
    -- 关注资源升级事件
    EventMgr.register("UILogin", event.UPGRADE_BY_SERVER_VER, function(para)
        -- 服务器支持版本号
        local serverSupportVersion = para.ver;
        -- 回调函数
        local callback = para.callback;

        print("serverSupportVersion:" .. serverSupportVersion);

        -- 保存目标版本号
        UserDefaultM.setStringForKey("server_support_ver", serverSupportVersion);

        -- 显示确认界面，提示玩家重新启动客户端进行版本匹配更新
        local function doComfirm()
			local function onOK()
				-- 重置APP
				rebootApp();
			end

            local uiForm = confirm2(CONFIRM_TYPE_OK, getLocStr("new_version_found_title"), getLocStr("new_version_found_desc"), onOK);
            uiForm:hideBackBtn();
        end

        doComfirm();
    end);

    -- 关注账号验证结果
    EventMgr.register("UILogin", event.MESSAGE_DONE, function(para)
        if para[1] == "MSG_LOGIN" then
            -- 登录gs的消息

            local args = para[2] or {};

            -- 失败了才处理
            if args.succ ~= 1 then
                if args.msg then
                    alert(getDialogStr(args.msg));
                end

                -- 关闭通信中窗口
                closeCommunicatingForm();
            end

            return;
        end

        if para[1] ~= "MSG_AUTH_ACCOUNT_RESULT" then
            return
        end

        if para[2].result ~= 1 then
            self.isLogin = false;

            -- 如果只是版本号不支持，提示玩家重新更新客户端
            if para[2].msg == "dialog_26" or para[2].msg == "dialog_28" then
                if POINEER_SERVER == 1 then
                    self:handlePoineerServer();
                    return;
                end

                local function okFunc()
                    -- 此时转入自动更新存在问题，参见SLIMEC-2521，需要玩家手工重启APP
                    return;
                end

                confirm2(CONFIRM_TYPE_OK, "", getDialogStr(para[2].msg), okFunc);
            elseif para[2].result == LOGIN_AUTH_ACCOUNT_NOT_ACTIVATED then
                -- 账号未激活
                local args = para[2].para or {};
                local account = args.account;
                local channel = args.channel;
                require "game/ui/form/login/UIAccountActivate";
                local uiForm = UIAccountActivate.create(account, channel);
                UIMgr.getCurrentScene():removeFormByName("UIAccountActivate");
                UIMgr.getCurrentScene():addForm(uiForm);
            elseif para[2].result == LOGIN_AUTH_GUEST_ACCOUNT_LIMIT then
                -- 游客账号受限
                local args = para[2].para or {};
                local bindedAcounts = args.bind_accounts;
                self.bindedAccounts = bindedAcounts;
                self:limitGuestFunc();
            elseif para[2].msg == "dialog_255" or para[2].msg == "dialog_259" then
                -- 当前设备无法使用游客模式登录
                local function okFunc()
                    local isForbidGuest = true;
                    UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
                    local UIChannelSelect = UIChannelSelect.create(isForbidGuest);
                    UIMgr.getCurrentScene():addForm(UIChannelSelect);
                end
                confirm2(CONFIRM_TYPE_OK, getLocStr("slime_note"), getDialogStr(para[2].msg), okFunc);
            else
                -- 其他情况，统一弹提示
                showHint(getDialogStr(para[2].msg), 1);
            end

            -- 关闭通信中窗口
            closeCommunicatingForm();
        else
            alert(getLocStr("auth_success"));

            -- 播放登录成功的音效
            AudioM.playFx("button_login");
        end
    end);

    -- 关注登录成功的消息，进入主场景
    EventMgr.register("UILogin", event.LOGIN_OK, function()
        trace("UILogin", "登录成功，进入主场景");
        UIMgr.setCurState(UIMgr.STATE_MAIN);

        -- 保存用户名
        local userName = self.editName:getText();
        userName = AccountM.removeTabAndSpace(userName);
        UserDefaultM.setStringForKey("UserName", userName);

        -- 保存密码
        local password = self.editPassword:getText();
        local data = MyRc4.encrypt(password, "kkkk");
        local final = MyBase64.encode(data);
        UserDefaultM.setStringForKey("Password", final);
    end);

    -- 关注G+账号登录成功的事件
    EventMgr.register("UILogin", event.GOOGLE_CONNECTED, function()
        if ME.isInGame then
            -- 已经在游戏中，不处理
            return;
        end

        if not _G["request_google_login"] then
            -- 未发起过请求，不处理（这种情况应该是玩家进入游戏时就已经登录了G+账号）
            trace("UILogin", "玩家已经登录G+账号，可点击开始游戏请求服务器验证。");
            return;
        end

        -- 移除G+登录窗口
        if UIMgr.getCurrentScene():isOpen("UIChannelSelect") then
            UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
        end

        trace("UILogin", "G+账号登录成功，请求服务器认证");
        _G["request_google_login"] = nil;
        auth3rdPlatform(CHANNEL_GOOGLE);

        -- 进入通信显示
        self:enterCommunicateMode();
    end);

    -- 关注G+账号登录失败的事件
    EventMgr.register("UILogin", event.GOOGLE_CONNECT_ERROR, function(param)
        local function okFunc()
            -- 退出游戏
            exitSystem();
        end

        print("GOOGLE_CONNECT_ERROR, param:" .. param);
        if param == "not_available" then
            confirm2(CONFIRM_TYPE_OK, "", getLocStr("google_play_not_available"), okFunc);
        elseif param == "connect_fail" then
            confirm2(CONFIRM_TYPE_OK, "", getLocStr("google_play_connect_fail"), okFunc);
        end
    end);

    -- 关注谷歌账号权限声明事件
    EventMgr.register("UILogin", event.SHOW_PERMISSION_EXPLAIN, function(callback)
        showPermissionExplainUI(callback);
    end);

    -- 关注facebook账号登录成功的事件
    EventMgr.register("UILogin", event.FACEBOOK_CONNECTED, function()
        if ME.isInGame then
            -- 已经在游戏中，不处理
            return;
        end

        local channel = getFacebookChannelName();
        local path = string.format("request_%s_login", channel);

        if not _G[path] then
            -- 未发起过请求，不处理（这种情况应该是玩家进入游戏时就已经登录了fb账号）
            trace("UILogin", "玩家已经登录fb账号，可点击开始游戏请求服务器验证。");
            return;
        end

        -- 移除登录窗口
        if UIMgr.getCurrentScene():isOpen("UIChannelSelect") then
            UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
        end

        trace("UILogin", "fb账号登录成功，请求服务器认证");
        _G[path] = nil;
        auth3rdPlatform(channel);

        -- 进入通信显示
        self:enterCommunicateMode();
    end);

    -- 关注GameCenter登录成功的事件
    EventMgr.register("UILogin", event.GAME_CENTER_CONNECTED, function()
        if ME.isInGame then
            -- 已经在游戏中，不处理
            return;
        end

        -- 未发起过请求，不处理
        -- 由于每当应用从后台切换到前台时，都会触发此回调，如果不做下面的判断，当用户在登录界面切换一下前后台
        -- 客户端就会自动发起登录了，见任务 SLIMEC-5679
        if not _G["request_gamecenter_login"] then
            trace("UILogin", "玩家已经登录GameCenter账号，可点击开始游戏请求服务器验证。");
            return;
        end

        -- 移除登录窗口
        if UIMgr.getCurrentScene():isOpen("UIChannelSelect") then
            UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
        end

        trace("UILogin", "GameCenter账号登录成功，请求服务器认证");
        _G["request_gamecenter_login"] = nil;
        auth3rdPlatform(CHANNEL_GAME_CENTER);

        -- 进入通信显示
        self:enterCommunicateMode();
    end);

    -- 关注GameCenter登录失败的事件
    EventMgr.register("UILogin", event.GAME_CENTER_ERROR, function()
        alert(getLocStr("third_account_auth_fail"));
    end);

    -- 关注第三方渠道账号登录失败的事件
    EventMgr.register("UILogin", event.THIRD_ACCOUNT_LOGIN_FAIL, function(args)
        local channel = args.channel;          -- 实际登录游戏的渠道
        local channelRaw = args.channel_raw;   -- 原始渠道
        local flagPath = string.format("request_%s_login", channelRaw or channel);
        _G[flagPath] = nil;
        alert(getLocStr("third_account_auth_fail"));
        closeCommunicatingForm();
    end);

    -- 关注第三方渠道账号登录成功的事件
    EventMgr.register("UILogin", event.THIRD_ACCOUNT_LOGINED, function(args)
        local channel = args.channel;          -- 实际登录游戏的渠道
        local channelRaw = args.channel_raw;   -- 原始渠道
        local flagPath = string.format("request_%s_login", channelRaw or channel);

        if ME.isInGame then
            -- 已经在游戏中，不处理
            return;
        end

        if not _G[flagPath] then
            -- 未发起请求，不处理
            trace("UILogin", "玩家已经登录%s账号，可点击开始游戏请求服务器验证。", channel);
            return;
        end

        -- 如果渠道选择窗口是打开的，需要移除
        if UIMgr.getCurrentScene():isOpen("UIChannelSelect") then
            UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
        end

        trace("UILogin", "%s账号登录成功，请求服务器认证。", channel);

        _G[flagPath] = nil;
        auth3rdPlatform(channel);

        -- 进入通信显示
        self:enterCommunicateMode();
    end);

    -- 关注游客账号已经绑定的事件
    EventMgr.register("UILogin", event.GUEST_ACCOUNT_BINDED, function()
        -- 这个部分先不做
        -- local function onOK()
        --     closeCommunicatingForm();
        --     setLastAccountChannel("");

        --     Socket.disconnect();
        --     exitApp();
        -- end

        -- local confirm = confirm2(CONFIRM_TYPE_OK, getLocStr("guest_mode"), getLocStr("guest_mode_tip3"),
        --     onOK);
        -- confirm:hideBackBtn();
    end);

    -- 关注网络连接断开的事件
    EventMgr.register("UILogin", event.NETWORK_DISCONNECTED, function()
        -- 关闭通信中窗口
        --closeCommunicatingForm();

        if self.isLogin then
            self.isLogin = false;
        end
    end);

    -- 注册获得焦点的回调
    EventMgr.register("UILogin", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UILogin" then
            self:checkTipBtn();
        end

        if para["lose"] == "UICommunicating" then
            -- 停止各种定时事件
            self.timerNode:stopAllActions();
        end
    end);

    -- 关注账号激活事件
    EventMgr.register("UILogin", event.ACCOUNT_ACTIVATE_RESULT, function(args)
        local result  = args.result;
        local msg     = args.msg;
        local channel = args.channel;
        alert(getDialogStr(msg));

        -- 成功了
        if result == 1 then
            -- 关闭相应界面
            closeFormByName("UIAccountActivate");

            -- 自动登录
            auth3rdPlatform(channel);
        end
    end);

    -- idfa获取失败
    EventMgr.register("UILogin", event.GET_IDFA_FAIL, function()
        confirm2(CONFIRM_TYPE_OK, getLocStr("guest_login_tip"), getLocStr("get_idfa_fail"));
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            -- 移除所有事件回调
            EventMgr.removeAll("UILogin");

            -- 移除通信中界面
            -- 此处不移除，等到MSG_ENTER_WORLD到达后在移除 SLIMEC-3128
            -- closeCommunicatingForm();
        elseif ev == "enter" then
            -- 动画效果
            local function delay()
                self:playBackgroudEffect();
            end
            performWithDelay(self, delay, 0.1);

            self:initBackEventHandler();
        end
    end);
end

-- 限制游客登陆
function UILogin:limitGuestFunc()
    local bindedAcounts = self.bindedAccounts;
    local function okFunc()
        local isForbidGuest = true;
        UIMgr.getCurrentScene():removeFormByName("UIChannelSelect");
        local UIChannelSelect = UIChannelSelect.create(isForbidGuest, bindedAcounts);
        UIMgr.getCurrentScene():addForm(UIChannelSelect);
    end

    local dialog = getDialogStr("dialog_255");
    if PUBLISH_PLATFORM == PUBLISH_TYPE_AMAZON then
        dialog = getDialogStr("dialog_259");
    end

    if type(bindedAcounts) == "table" and #bindedAcounts == 1 then
        local bindedChannels = {};
        for _, account in ipairs(bindedAcounts) do
            local index = string.find(account, "_");
            local channel = string.sub(account, 1, index - 1);
            table.insert(bindedChannels, channel);
        end

        if bindedChannels[1] == CHANNEL_GOOGLE then
            dialog = getDialogStr("dialog_258");
        elseif bindedChannels[1] == CHANNEL_FACEBOOK_GP or bindedChannels[1] == CHANNEL_FACEBOOK_AM then
            dialog = getDialogStr("dialog_257");
        elseif bindedChannels[1] == CHANNEL_AMAZON then
            dialog = getDialogStr("dialog_260");
        end
    end
    confirm2(CONFIRM_TYPE_OK, getLocStr("slime_note"), dialog, okFunc);
end

-- 设置登陆框可见状态
function UILogin:setLoginFormVisible(flag)

    local mask = self.node:getChildByName("mask");
    local ct = self.node:getChildByName("ct");

    if flag == true then
        local oldScale = ct:getScale();

        -- ct从中心弹出
        ct:setScale(oldScale * 0.8);
        local scaleUp1 = cc.EaseIn:create(cc.ScaleTo:create(0.1, oldScale * 1.05), 0.3);
        local scaleUp2 = cc.ScaleTo:create(0.05, oldScale);
        ct:runAction(cc.Sequence:create(scaleUp1, scaleUp2));
    end
    local startNode = findChildByName(self.node, "ct2/start");
    ct:setVisible(flag);
    mask:setVisible(flag);
    startNode:setVisible(not flag);
end

-- 设置登录不可见
function UILogin:setLoginFormInvisible()
    local mask = self.node:getChildByName("mask");
    local ct = self.node:getChildByName("ct");
    local startNode = findChildByName(self.node, "ct2/start");
    ct:setVisible(false);
    mask:setVisible(false);
    startNode:setVisible(false);
end

-- 设置遮罩的显隐
function UILogin:setMaskVisible(isVisible)
    local mask = self.node:getChildByName("mask");
    mask:setVisible(isVisible);
end

-- 播放背景动画
function UILogin:playBackgroudEffect()
    local effect1Node = findChildByName(self.node, "ct2/effect1_node");
    local effect2Node = findChildByName(self.node, "ct2/effect2_node");
    local slime1Node = findChildByName(self.node, "ct2/slime1_node");
    local slime2Node = findChildByName(self.node, "ct2/slime2_node");
    local slime3Node = findChildByName(self.node, "ct2/slime3_node");
    local lightNode = findChildByName(self.node, "ct2/light_node");
    local startNode = findChildByName(self.node, "ct2/start");

    local effectList = self.initEffects;

    -- 获得主题背景effect
    local mainEffectId = effectList["main_id"];
    -- 标题effect
    local titleEffectId = effectList["title_id"];
    -- 标题背景effect
    local titleBgEffectId = effectList["title_bg_id"];
    -- 左边的冈布奥
    local leftGumballEffectId  = effectList["left_gumball"];
    -- 中间的冈布奥
    local centerGumballEffectId = effectList["center_gumball"];
    -- 右边的冈布奥
    local rightGumballEffectId = effectList["right_gumball"];

    -- 节日光效（不一定会有，会出现在主题光效的某一帧）
    local festivalEffectInfo = effectList["festival_effect"];

    local festivalEffectId, appearFrame, loopFirstFrame, loopLastFrame, isInTop;
    if type(festivalEffectInfo) == "table" then
        festivalEffectId = festivalEffectInfo["effect_id"];
        appearFrame = festivalEffectInfo["appear_frame"];
        loopFirstFrame = festivalEffectInfo["first_frame"];
        loopLastFrame  = festivalEffectInfo["last_frame"];
        isInTop = festivalEffectInfo["festival_in_top"];
    end

    local festivalNode;
    if isInTop then
        festivalNode = findChildByName(self.node, "ct2/festival_node2");
    else
        festivalNode = findChildByName(self.node, "ct2/festival_node");
    end

    -- 到了第120帧开始循环播放（标题背景动画）
    local function frameEventFunc1(titleframe)
        if titleframe.getEvent and titleframe:getEvent() == "pilor" then
            local index = titleframe:getFrameIndex();
            if index == 218 then
                self.loginEffect1.action:gotoFrameAndPlay(120, false);
            end
        end
    end

    local _, loginEffect1 = playEffect(effect1Node, titleBgEffectId, -381, 205, frameEventFunc1);
    self.loginEffect1 = loginEffect1;

    local _, loginEffect3 = playEffect(effect2Node, titleEffectId, -381, 205);
    self.loginEffect3 = loginEffect3;

    -- 使用缓存光效时，副标题可能存在
    local guadianNode = findChildByName(self.loginEffect3, "guadian");
    if guadianNode then
        local subTitle = findChildByName(guadianNode, "sub_title_text");
        if subTitle then
            subTitle:removeFromParent();
        end
    end

    -- 节日装饰光效循环
    local function festivalFrameEventFunc(festivalFrame)
        if not loopFirstFrame or not loopLastFrame then
            return;
        end

        if festivalFrame.getEvent and festivalFrame:getEvent() == "pilor" then
            local index = festivalFrame:getFrameIndex();
            if index == loopLastFrame then
                self.festivalEffect.action:gotoFrameAndPlay(loopFirstFrame, false);
            end
        end
    end

    -- 播放主背景动画
    local function frameEventFunc2(frame)
        if frame.getEvent and frame:getEvent() == "pilor" then
            local index = frame:getFrameIndex();

            if index == 104 then
                -- 播放到104帧以后，动画不可以略过
                self.canSkipAnimation = false;

                -- 前排中间冈布奥的待机动画
                local slime1Node = findChildByName(self.node, "ct2/slime1_node");
                playEffect(slime1Node, centerGumballEffectId, -387, 871.5);
            elseif index == 109 then
                local slime2Node = findChildByName(self.node, "ct2/slime2_node");
                -- 左右两只冈布奥的待机动画
                playEffect(slime2Node, leftGumballEffectId, -211, 809);
                local slime3Node = findChildByName(self.node, "ct2/slime3_node");
                playEffect(slime3Node, rightGumballEffectId, -557.5, 819);

                self:startBtnEffect(startNode);
            elseif appearFrame ~= nil and index == appearFrame and festivalEffectId ~= nil then
                -- 节日光效
                local _, festivalEffect =playEffect(festivalNode, festivalEffectId, 0, 0, festivalFrameEventFunc);
                self.festivalEffect = festivalEffect;
            end
        end
    end

    local _, loginEffect2 = playEffect(lightNode, mainEffectId, -383.8, 86.8, frameEventFunc2);

    self.loginEffect2 = loginEffect2;
end

function UILogin:startBtnEffect(startNode)
    if isOverseaPackage() and getLang() ~= "en" then
        local kerning, textScale = 0, 1;
        if getLang() == "th" then
            kerning = 1;
        elseif getLang() == "ja" then
            kerning, textScale = -4, 0.78;
        elseif getLang() == "ko" then
            kerning, textScale = -4, 0.9;
        elseif getLang() == "pt" then
            kerning, textScale = -3, 0.78;
        elseif getLang() == "es" then
            kerning, textScale = -2, 0.74;
        elseif getLang() == "fr" then
            kerning, textScale = -2, 0.85;
        elseif getLang() == "ru" then
            kerning, textScale = -2, 0.68;
        elseif getLang() == "de" then
            kerning, textScale = -2, 0.74;
        end

        textScale = textScale / getLocFontSizeMulti();

        local guadianNode = findChildByName(self.loginEffect3, "guadian");
        if guadianNode then
            local titleLabel = ccui.Text:create();
            titleLabel:setPosition(0,0);

            titleLabel:setName("sub_title_text");

            guadianNode:addChild(titleLabel);

            local subTitleStr = getLocStr("login_sub_title");
            TextStyleM.setTextStyle(titleLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BROWN_YELLOW, false, kerning);
            TextStyleM.setShadowStyle(titleLabel, cc.size(-0.3, -2.5));
            TextStyleM.setOutlineStyle(titleLabel, 1.6, TEXT_COLOR_DARK_BROWN, true);

            titleLabel:setString(subTitleStr);
            titleLabel:setOpacity(0);
            titleLabel:setScale(textScale);
            local fadeIn = cc.FadeIn:create(0.3);
            titleLabel:runAction(fadeIn);
        end
    end

    -- 显示登录
    startNode:setVisible(true);

    local startBg = findChildByName(startNode, "bg");
    local startLabel = findChildByName(startNode, "start_label");
    startLabel:setScale(0.1);
    startBg:setScale(0.1);
    local function createAction(node)
        local scaleUp1 = cc.ScaleTo:create(0.2, 1.3);
        local delay = cc.DelayTime:create(0.1);
        local scaleUp2 = cc.ScaleTo:create(0.1, 1);
        local callFunc = cc.CallFunc:create(function ()
            playBubbleSlightAnima(node, 0.05, 1.2);
        end);
        return cc.Sequence:create(scaleUp1, scaleUp2, delay, callFunc);
    end
    local action1 = createAction(startBg);
    startBg:runAction(action1);

    local action2 = createAction(startLabel);
    startLabel:runAction(action2);

    local function shakeStart()
        playShakeEffect(startNode, 0.03, 3, 3);

        performWithDelay(self, shakeStart, 3);
    end

    performWithDelay(self, shakeStart, 3);
end

-- 停止动画效果
function UILogin:stopEffect()
    local slime1Node = findChildByName(self.node, "ct2/slime1_node");
    local slime2Node = findChildByName(self.node, "ct2/slime2_node");
    local slime3Node = findChildByName(self.node, "ct2/slime3_node");
    pauseNode(slime1Node);
    pauseNode(slime2Node);
    pauseNode(slime3Node);
end

-- 处理返回键输入
function UILogin:registerBackKeyEventHandler()
    local mask = self.node:getChildByName("mask");

    local function onKeyReleased(keyCode, event)
        if keyCode == cc.KeyCode.KEY_BACK then
            UIMgr.handleBackEvent();
        end
    end

    local listener = cc.EventListenerKeyboard:create()
    listener:registerScriptHandler(onKeyReleased, cc.Handler.EVENT_KEYBOARD_RELEASED )

    local eventDispatcher = mask:getEventDispatcher()
    eventDispatcher:addEventListenerWithSceneGraphPriority(listener, mask);
end

-- 注册back按键的处理函数
function UILogin:initBackEventHandler()
    exitGamePrompt(self);
end

-- 调整位置
function UILogin:resize()
    local node = self.node;

    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local bg = node:getChildByName("bg");
    bg:setPosition(w / 2, h / 2);
    local scaleCo = math.max(w / 768, h / 1136);
    bg:setScale(scaleCo);

    -- 背景和光效重叠需要与背景一样缩放
    local bt = node:getChildByName("ct2");
    bt:setPosition(w / 2, h / 2);
    bt:setScale(scaleCo);

    local mask = node:getChildByName("mask");
    mask:setPosition(w / 2, h / 2);
    mask:setContentSize(w, h);

    local ct = node:getChildByName("ct");
    ct:setPosition(w / 2, h * ct:getPositionY() / DESIGN_HEIGHT);
    ct:setScale(w / DESIGN_WIDTH);

    local version = node:getChildByName("version");
    version:setPositionX(version:getPositionX() * w / DESIGN_WIDTH);
    version:setPositionY(version:getPositionY() * h / DESIGN_HEIGHT);
    version:setScale(w / DESIGN_WIDTH);

    local accountSwitchBtn = findChildByName(node, "account_switch");
    accountSwitchBtn:setPositionX(accountSwitchBtn:getPositionX() * w / DESIGN_WIDTH);
    accountSwitchBtn:setPositionY(accountSwitchBtn:getPositionY() * h / DESIGN_HEIGHT);
    accountSwitchBtn:setScale(accountSwitchBtn:getScale()*(w/DESIGN_WIDTH));

    local accountRegBtn = findChildByName(node, "account_reg");
    accountRegBtn:setPositionX(accountRegBtn:getPositionX() * w / DESIGN_WIDTH);
    accountRegBtn:setPositionY(accountRegBtn:getPositionY() * h / DESIGN_HEIGHT);
    accountRegBtn:setScale(accountRegBtn:getScale()*(w/DESIGN_WIDTH));

    local tipImg = findChildByName(node, "tip");
    tipImg:setPositionX(tipImg:getPositionX() * w / DESIGN_WIDTH);
    tipImg:setPositionY(tipImg:getPositionY() * h / DESIGN_HEIGHT);
    if not self.tipImgScale then
        self.tipImgScale = tipImg:getScale()*(w/DESIGN_WIDTH);
    end
    tipImg:setScale(self.tipImgScale);

    local tipBg = findChildByName(node, "tip_bg");
    tipBg:setPositionX(tipBg:getPositionX() * w / DESIGN_WIDTH);
    tipBg:setPositionY(tipBg:getPositionY() * h / DESIGN_HEIGHT);

    -- 跟tipImg一起缩放
    if not self.tipImgScale then
        self.tipImgScale = tipImg:getScale()*(w/DESIGN_WIDTH);
    end
    tipBg:setScale(self.tipImgScale);
end

-- 系统信息按钮相关处理
function UILogin:systemBtn()
    local tipImg = findChildByName(self.node, "tip");
    local tipBg  = findChildByName(self.node, "tip_bg");
    local function onClickTip(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            -- 1.变小
            local downTime  = 0.25/2;
            local scaleDown = cc.ScaleTo:create(downTime, self.tipImgScale * 0.8);
            tipImg:runAction(scaleDown);
        elseif eventType == ccui.TouchEventType.ended then
            -- 2.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, self.tipImgScale * 1);
            tipImg:runAction(scaleUp);
        elseif eventType == ccui.TouchEventType.canceled then
            -- 3.变大
            local downTime  = 0.25/2;
            local scaleUp = cc.ScaleTo:create(downTime, self.tipImgScale * 1);
            tipImg:runAction(scaleUp);
        end

        if eventType == ccui.TouchEventType.ended then
            require "game/ui/form/setting/UILoginSetting";
            local uiForm = UILoginSetting.create();
            UIMgr.getCurrentScene():addForm(uiForm);
        end
    end
    tipImg:addTouchEventListener(onClickTip);
    tipBg:addTouchEventListener(onClickTip);
    self:checkTipBtn();
end

-- 检查提示闪烁
function UILogin:checkTipBtn()
    local tipImg = findChildByName(self.node, "tip");
    tipImg:stopAllActions();

    if not self.tipImgScale then
        local w = cc.Director:getInstance():getOpenGLView():getFrameSize().width;
        self.tipImgScale = tipImg:getScale()*(w/DESIGN_WIDTH);
    end
    tipImg:setScale(self.tipImgScale);

    if MaintainBulletinM.isSysMaintaining()
       or not GameBoardM.hasReadFirstBoard() then
        -- 维护中/未读过闪烁
        playBubbleAnima(tipImg, false, self.tipImgScale);
    end
end

-- 显示系统维护公告
function UILogin:showMaintainConfirm(bulletin)
    local title   = bulletin.title;
    local content = bulletin.content;

    local function okFunc()
        -- 退出游戏
        exitSystem();
    end

    -- 加上世界时间
    local timeText = MaintainBulletinM.getWorldTimeDesc();
    content = spliceLocStr(content, "\n\n", timeText);

    confirm2(CONFIRM_TYPE_OK, title, content, okFunc, nil,
        nil, nil, { ["backFunc"] = okFunc,
        ["leftTimeDesc"] = {"maintain", content, MaintainBulletinM.calcLeftTime()}});
end

-- 检查自动登陆
function UILogin:tryAutoLogin()
    if not LoginM.getAutoLogin() then
        -- 不需要自动登陆
        return;
    end

    if isAndroidPlatform() or isIphonePlatform() or isIpadPlatform() then
        -- 如果已经登录了第三方平台账号，则直接请求登录游戏
        if not EXPRESS_LOGIN and hasLogin3rdPlatform() then
            -- 请求服务器认证
            auth3rdPlatform();

            -- 进入通信显示
            self:enterCommunicateMode();
        elseif isOverseaPackage() then
            -- 前面登陆应该已经验证过GOOGLE账号
            -- 跑到这里就不管了
            -- TODO
        else
            -- 尝试自动登陆
            self:tryLogin();
        end
    else
        -- 尝试自动登陆
        self:tryLogin();
    end
end

-- 尝试登陆
function UILogin:tryLogin()
    local userName = self.editName:getText();
    userName = AccountM.removeTabAndSpace(userName);

    if userName == "" then
        alert(getLocStr("please_input_username"));
        return;
    end

    local passwdInput = self.ct:getChildByName("input_passwd");
    local password = self.editPassword:getText();

    -- 判断网络状态
    if (not NetworkStatus.isWifiConnected() and
        not NetworkStatus.isMobileConnected()) then
        alert(getLocStr("network_is_unavailable"));
        return;
    end

    -- 是否需要强制更新完整包
    if FORCE_UPDATE_FULL_PKG == 1 then
        if isAndroidPlatform() then
            local content = getLocStr("package_download_tip");
            if PUBLISH_PLATFORM == PUBLISH_TYPE_GOOGLE_PLAY then
                -- GooglePlay平台
                content = getLocStr("package_google_download_tip");
            end
            showDownloadDialog(getLocStr("package_download_title"), content,
                getLocStr("btn_text_package_download"), MaintainBulletinM.getPackageDownloadUrl());
        end
        print("FORCE_UPDATE_FULL_PKG");
        return;
    end

    -- 判断需求引擎版本和实际引擎版本号是否匹配
    if REQUIRE_ENGINE_VERSION ~= Version.getEngineVersion() and not EXPRESS_LOGIN then
        alert(getLocStr("required_engine_version_mismatch"));
        return;
    end

    if self.isLogin and Socket.isConnected() then
        alert(getLocStr("login_hint"));
        return;
    end

    self.isLogin = true;

    local account;

    -- 便接管账号,不需要对账户进行@转#的操作
    if TEST_TAKEOVER == 1 then
        account = userName;
    else
        account = string.gsub(userName, "@", "#");
    end

    -- TODO: 压力测试
    if STRESS_TEST then
        StressTest.start(account, password);
    elseif not EXPRESS_LOGIN then
        local platformName = "qc";
        if TEST_TAKEOVER == 1 then
            -- 为方便接管账号输入，以_前面的字符串作为平台名称
            local list = string.explode(account, "_");
            if #list > 1 then
                platformName = list[1];
                table.remove(list, 1);
                account = table.concat(list, "_");
            end
        end

        -- 不能快捷登陆
        Operation.cmd_login_cc(account, password, CC_IP, CC_PORT, SUPPORT_VERSION, {["3rdplatform"] = platformName });
    else
        Operation.cmd_login(account, SERVER_IP, SERVER_PORT);
    end

    -- 进入通信显示
    self:enterCommunicateMode();

    self:stopEffect();
end

-- 打开第三方账号登录窗口
function UILogin:show3rdAccountLogin(channel)
    local ret = show3rdAccountLogin(channel);

    if ret == true then
        -- 打上登录请求标识
        local path = string.format("request_%s_login", channel);
        _G[path] = true;
    end
end

-- 处理先驱服提示信息
function UILogin:handlePoineerServer()
    -- 先驱服利用supportversion不匹配来提示原来的uc玩家到新的游戏专区下载西瓜平台的安装包
    local function onGoto()
        local url = "";
        if PUBLISH_PLATFORM == PUBLISH_TYPE_UC then
            url = "http://www.9game.cn/zdbslm/";
        elseif PUBLISH_PLATFORM == PUBLISH_TYPE_MI then
            url = "http://game.xiaomi.com/app-appdetail--app_id__580464.html";
        end
        openUrl(url);

		closeCommunicatingForm();
    end

    local function onBack()
        closeCommunicatingForm();
    end

    confirm2(CONFIRM_TYPE_OK, getLocStr("game_board"), getLocStr("poineer_server_hint"), onGoto, nil, getLocStr("btn_text_go"), nil, {backFunc=onBack});
end

-- 开始按钮bg适配
function UILogin:resizeStartBg(startLabel, startBg)
    local labelWidth = startLabel:getContentSize().width;

    local bgSize = startBg:getContentSize();

    if labelWidth + 30 > bgSize.width then
        startBg:setContentSize(labelWidth + 30, bgSize.height);
    end
end